package org.dromara.finance.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class ContractReferenceCheckUtil {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 删除前校验引用
     *
     * @param contractType "sale" 或 "purchase"
     * @param ids          要删除的合同ID集合
     */
    public void checkBeforeDelete(String contractType, Collection<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }

        // 不同合同类型的校验SQL集合
        List<CheckConfig> checkConfigs = new ArrayList<>();

        if ("sale".equalsIgnoreCase(contractType)) {
            // 销售合同引用校验
            checkConfigs.add(new CheckConfig(
                "purchase_contract", "sale_contract_id", null, "采购合同"));
            checkConfigs.add(new CheckConfig(
                "sale_invoice", "sale_contract_id", null, "销售发票"));
            checkConfigs.add(new CheckConfig(
                "bill", "contract_id", "bill_type=1", "销售收款单"));
        } else if ("purchase".equalsIgnoreCase(contractType)) {
            // 采购合同引用校验
            checkConfigs.add(new CheckConfig(
                "purchase_invoice", "purchase_contract_id", null, "采购发票"));
            checkConfigs.add(new CheckConfig(
                "bill", "contract_id", "bill_type=2", "采购付款单"));
        } else {
            throw new IllegalArgumentException("不支持的合同类型: " + contractType);
        }

        // 拼接 SQL 并执行校验
        String inClause = ids.stream().map(id -> "?").collect(Collectors.joining(","));
        Object[] params = ids.toArray();

        for (CheckConfig cfg : checkConfigs) {
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT COUNT(*) FROM ").append(cfg.getTableName())
                .append(" WHERE ").append(cfg.getColumnName())
                .append(" IN (").append(inClause).append(")");
            if (cfg.getExtraCondition() != null) {
                sql.append(" AND ").append(cfg.getExtraCondition());
            }

            Integer count = jdbcTemplate.queryForObject(sql.toString(), Integer.class, params);
            if (count != null && count > 0) {
                throw new RuntimeException("存在被【" + cfg.getLabel() + "】引用的合同，禁止删除！");
            }
        }
    }

    public void checkReferenceArchive(String table, String column, Collection<Long> ids, String entityName) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        String sql = String.format("SELECT COUNT(1) FROM %s WHERE %s IN (:ids)", table, column);
        Map<String, Object> params = Collections.singletonMap("ids", ids);
        // 使用 NamedParameterJdbcTemplate 处理 IN 条件
        NamedParameterJdbcTemplate namedTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
        Integer count = namedTemplate.queryForObject(sql, params, Integer.class);
        if (count != null && count > 0) {
            throw new RuntimeException(entityName + "已被合同引用，无法删除");
        }
    }

    /**
     * 内部配置类，描述一条引用关系
     */
    @Data
    @AllArgsConstructor
    static class CheckConfig {
        private String tableName;
        private String columnName;
        private String extraCondition; // 例如 bill_type=1
        private String label;          // 提示文案
    }
}

